<template>
  <activity-panel title="操作面板" width="600px">
    <el-button type="primary" @click="doCluster">进行点聚合</el-button>
    <el-button type="primary" @click="doCluster2">进行点聚合2</el-button>
    <el-button type="primary" @click="doPolygonCluster"
      >进行多边形聚合</el-button
    >
    <el-button type="primary" @click="doPolygonCluster2"
      >多边形聚合解决海量数据问题</el-button
    >
  </activity-panel>

  <base-map :center="center" :zoom="zoom" />
</template>

<script setup>
import { ref, onMounted, nextTick } from "vue";

import * as turf from "@turf/turf";

import WebGLVectorLayer from "ol/layer/WebGLVector";
import { Vector as VectorLayer } from "ol/layer";
import { Vector as VectorSource, Cluster } from "ol/source";
import Feature from "ol/feature";
import { Point, LineString, Polygon, Circle } from "ol/geom";
import {
  Style,
  Stroke,
  Fill,
  Circle as CircleStyle,
  Icon,
  Text,
  RegularShape,
} from "ol/style";
import { boundingExtent } from "ol/extent";
import { GeoJSON } from "ol/format";
import Select from "ol/interaction/Select.js";
import { randomPolygonFeature } from "@/utils/random.js";

// const center = [108.89766828762245, 33.42875613964681];
// const zoom = 5;

function doCluster() {
  // 矢量数据源
  const weatherStationSource = new VectorSource({
    format: new GeoJSON(),
    url: "src/data/气象站点/stations-wgs.geojson",
  });

  // 聚合数据源
  const clusterSource = new Cluster({
    distance: 40,
    source: weatherStationSource,
    geometryFunction: function (feature) {
      const type = feature.get("type");

      if (type == "基本站") {
        return null;
      }

      return feature.getGeometry();
    },
  });

  const weatherStationLayer = new VectorLayer({
    properties: {
      name: "气象站点",
      id: "weather-station",
    },
    source: clusterSource,
    // source: weatherStationSource,
  });

  weatherStationLayer.setStyle([
    {
      filter: [">", ["get", "features", "length"], 1],
      style: [
        {
          "circle-radius": 10, //圆半径
          "circle-fill-color": "#3399CC", //圆填充颜色
          "circle-stroke-width": 1.25, //圆边框宽度
          "circle-stroke-color": "#fff", //圆边框颜色
        },
        {
          "text-value": ["to-string", ["get", "features", "length"]], //文本内容
          "text-fill-color": "#fff", //文本颜色
        },
      ],
    },
    {
      else: true,
      style: [
        {
          "circle-radius": 10, //圆半径
          "circle-fill-color": "#3399CC", //圆填充颜色
          "circle-stroke-width": 1.25, //圆边框宽度
          "circle-stroke-color": "#fff", //圆边框颜色
        },
      ],
    },
  ]);

  window.map.addLayer(weatherStationLayer);

  map.on("click", e => {
    weatherStationLayer.getFeatures(e.pixel).then(clickedFeatures => {
      if (clickedFeatures.length) {
        // Get clustered Coordinates
        const features = clickedFeatures[0].get("features");
        if (features.length > 1) {
          const extent = 
          boundingExtent(
            features.map(r => r.getGeometry().getCoordinates())
          );
          map
            .getView()
            .fit(extent, { duration: 1000, padding: [50, 50, 50, 50] });
        }
      }
    });
  });

  map.on("pointermove", event => {
    weatherStationLayer.getFeatures(event.pixel).then(features => {
      // Change the cursor style to indicate that the cluster is clickable.
      if (features.length > 0) {
        map.getTargetElement().style.cursor =
          features[0].get("features").length > 1 ? "pointer" : "";
      }
    });
  });
}

function doCluster2() {
  // 矢量数据源
  const weatherStationSource = new VectorSource({
    format: new GeoJSON(),
    url: "src/data/气象站点/stations-wgs.geojson",
  });

  // 聚合数据源
  const clusterSource = new Cluster({
    distance: 40,
    source: weatherStationSource,
    geometryFunction: function (feature) {
      const type = feature.get("type");

      if (type == "基本站") {
        return null;
      }

      return feature.getGeometry();
    },
  });

  // 矢量图层
  const weatherStationLayer = new VectorLayer({
    properties: {
      name: "气象站点",
      id: "weather-station",
    },
    source: clusterSource,
  });

  // 聚合样式
  weatherStationLayer.setStyle([
    {
      filter: [">", ["get", "features", "length"], 1],
      style: [
        {
          "circle-radius": 10, //圆半径
          "circle-fill-color": "#3399CC", //圆填充颜色
          "circle-stroke-width": 1.25, //圆边框宽度
          "circle-stroke-color": "#fff", //圆边框颜色
        },
        {
          "text-value": ["to-string", ["get", "features", "length"]], //文本内容
          "text-fill-color": "#fff", //文本颜色
        },
      ],
    },
    {
      else: true,
      style: [
        {
          "circle-radius": 10, //圆半径
          "circle-fill-color": "#3399CC", //圆填充颜色
          "circle-stroke-width": 1.25, //圆边框宽度
          "circle-stroke-color": "#fff", //圆边框颜色
        },
      ],
    },
  ]);

  window.map.addLayer(weatherStationLayer);

  // 定义选中聚合点时的样式
  function selectStyleFunction(feature) {
    const styles = [
      new Style({
        image: new CircleStyle({
          radius: 10,
          fill: new Fill({
            color: "rgba(255, 255, 255, 0.01)",
          }),
        }),
      }),
    ];
    const originalFeatures = feature.get("features");
    let originalFeature;
    for (let i = originalFeatures.length - 1; i >= 0; --i) {
      originalFeature = originalFeatures[i];
      styles.push(
        new Style({
          geometry: originalFeature.getGeometry(),
          image: new RegularShape({
            radius: 3,
            radius2: 7,
            points: 5,
            angle: Math.PI,
            fill: new Fill({
              color: "rgba(255, 153, 0, 0.8)",
            }),
            stroke: new Stroke({
              color: "rgba(255, 204, 0, 0.2)",
              width: 1,
            }),
          }),
        })
      );
    }
    return styles;
  }

  // 定义选中聚合点的交互
  const select = new Select({
    condition: function (evt) {
      return evt.type == "pointermove" || evt.type == "singleclick";
    },
    style: selectStyleFunction,
  });

  window.map.addInteraction(select);
}

function doPolygonCluster() {
  // 矢量数据源
  const polygonSource = new VectorSource({
    features: randomPolygonFeature(window.map, 1000),
  });

  const clusterSource = new Cluster({
    distance: 40,
    source: polygonSource,
    geometryFunction: function (feature) {
      return feature.getGeometry().getInteriorPoint();
    },
    createCluster: function (point, features) {
      // 定义中心点
      const centerPoint = point.getCoordinates();
      // 定义正方形的半边长
      const halfSideLength = 0.5;

      // 计算正方形的四个顶点
      const topLeft = [
        centerPoint[0] - halfSideLength,
        centerPoint[1] + halfSideLength,
      ];
      const topRight = [
        centerPoint[0] + halfSideLength,
        centerPoint[1] + halfSideLength,
      ];
      const bottomRight = [
        centerPoint[0] + halfSideLength,
        centerPoint[1] - halfSideLength,
      ];
      const bottomLeft = [
        centerPoint[0] - halfSideLength,
        centerPoint[1] - halfSideLength,
      ];

      // 创建正方形的多边形坐标
      const squareCoordinates = [
        topLeft,
        topRight,
        bottomRight,
        bottomLeft,
        topLeft, // 闭合多边形
      ];

      // 创建多边形要素
      const squareFeature = new Feature({
        geometry: new Polygon([squareCoordinates]),
        features: features,
      });

      return squareFeature;
    },
  });

  const polygonLayer = new VectorLayer({
    properties: {
      name: "多边形图层",
      id: "polygonLayer",
    },
    // source: polygonSource,
    source: clusterSource,
  });

  window.map.addLayer(polygonLayer);
}

function doPolygonCluster2() {
  const polygonSource = new VectorSource({
    url: "src/data/河流三角网/BJ.json",
    format: new GeoJSON({
      dataProjection: "EPSG:4547",
      featureProjection: "EPSG:4326",
    }),
  });

  const clusterSource = new Cluster({
    distance: 40,
    source: polygonSource,
    geometryFunction: function (feature) {
      return feature.getGeometry().getPolygon(0).getInteriorPoint();
    },
    // createCluster: function (point, features) {
    //   if (features.length > 1) {
    //     const polygons = turf.featureCollection(
    //       features.map(f =>
    //         turf.polygon(f.getGeometry().getPolygon(0).getCoordinates())
    //       )
    //     );

    //     // debugger;

    //     const unionPolygon = turf.union(polygons);

    //     return new Feature({
    //       geometry: new Polygon(unionPolygon.geometry.coordinates),
    //       features: features,
    //     });
    //   } else {
    //     return features[0];
    //   }
    // },
  });

  const polygonLayer = new VectorLayer({
    properties: {
      name: "多边形图层",
      id: "polygonLayer",
    },
    source: clusterSource,
  });

  window.map.addLayer(polygonLayer);
}
</script>

<style lang="less" scoped></style>
